bitkeeper revision 1.560 (3fa8e3c6Enpzi2YxcvMiP8aJ3tXbnw)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 5 Nov 2003 11:49:26 +0000 (11:49 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 5 Nov 2003 11:49:26 +0000 (11:49 +0000)
hypervisor.h, setup.c, kernel.c:
  Finished guest support for suspend/resume.

extras/mini-os/kernel.c
xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c
xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h

index d7a6841cd10322ca809d29539aa61d7a34f4f5ae..ca9b8f4c6bdf9c59497aad01be12abfff76aa636 100644 (file)
@@ -110,7 +110,7 @@ void start_kernel(start_info_t *si)
     }; printk("\n");
     printk("  blk_ring:   0x%lx\n", si->blk_ring);
 #endif
-    printk("  dom_id:     %d\n",  si->dom_id);
+    printk("  dom_id:     %ld\n",  si->dom_id);
     printk("  flags:      0x%lx\n", si->flags);
     printk("  cmd_line:   %s\n",  si->cmd_line ? (const char *)si->cmd_line : "NULL");
 
index b952f123853d242984eda13995ca5d1b6a7cb894..ae7c587eabdb91bbba51a0b0ecb58739f7d324ed 100644 (file)
@@ -1057,15 +1057,35 @@ __initcall(setup_die_event);
  * Stop/pickle callback handling.
  */
 
+#include <asm/suspend.h>
+
 static void stop_task(void *unused)
 {
     /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
     extern void blkdev_suspend(void);
     extern void blkdev_resume(void);
     
+    unsigned long *pfn_to_mfn_frame_list = NULL;
+    suspend_record_t *suspend_record     = NULL;
     struct net_device *dev;
     char name[6];
-    int i;
+    int i, j;
+
+    if ( (pfn_to_mfn_frame_list = (unsigned long *)__get_free_page(GFP_KERNEL))
+         == NULL )
+        goto out;
+    if ( (suspend_record = (suspend_record_t *)__get_free_page(GFP_KERNEL))
+         == NULL )
+        goto out;
+
+    suspend_record->pfn_to_mfn_frame_list = 
+        virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
+    suspend_record->nr_pfns = max_pfn;
+
+    j = 0;
+    for ( i = 0; i < max_pfn; i += (PAGE_SIZE / sizeof(unsigned long)) )
+        pfn_to_mfn_frame_list[j++] = 
+            virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
 
     rtnl_lock();
     for ( i = 0; i < 10; i++ )
@@ -1083,7 +1103,11 @@ static void stop_task(void *unused)
     HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
     clear_fixmap(FIX_SHARED_INFO);
 
-    HYPERVISOR_stop();
+    memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info));
+
+    HYPERVISOR_stop(virt_to_machine(suspend_record) >> PAGE_SHIFT);
+
+    memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info));
 
     set_fixmap(FIX_SHARED_INFO, start_info.shared_info);
     HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
@@ -1101,6 +1125,12 @@ static void stop_task(void *unused)
             dev_open(dev);
     }
     rtnl_unlock();
+
+ out:
+    if ( pfn_to_mfn_frame_list != NULL )
+        free_page((unsigned long)pfn_to_mfn_frame_list);
+    if ( suspend_record != NULL )
+        free_page((unsigned long)suspend_record);
 }
 
 static struct tq_struct stop_tq;
index 785616e3fbba08cf4301380688537d263493d00a..08bc1faf6b9136cb37ca7ed40e29bd211cfec11e 100644 (file)
@@ -263,13 +263,14 @@ static inline int HYPERVISOR_exit(void)
     return ret;
 }
 
-static inline int HYPERVISOR_stop(void)
+static inline int HYPERVISOR_stop(unsigned long srec)
 {
     int ret;
+    /* NB. On suspend, control software expects a suspend record in %esi. */
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
-        "b" (SCHEDOP_stop) );
+        "b" (SCHEDOP_stop), "S" (srec) : "memory" );
 
     return ret;
 }